.TITLE TTCAN .IDENT /07.00/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; ; 06-FEB-78 PETER WANNHEDEN ; ; PREVIOUSLY MODIFIED BY: ; ; P. WANNHEDEN ; C. F. SPITZ ; D. R. DONCHIN ; M. S. HARVEY ; S. C. ADAMS ; B. S. MCCARTHY ; ; MODIFIED BY: ; ; S. C. ADAMS 4-AUGUST-87 07.00 ; SA475 -- CORRECT HANDLING OF SELECTIVE READ/WRITE KILLS ; ; ;+ ; THIS MODULE CONTAINS ENTRY POINTS FOR THE FOLLOWING ROUTINES ; CALLED BY THE EXECUTIVE: ; ; TTCAN - CANCEL IO ; TTPWUP - POWER-UP ;- ; ; .MCALL DCBDF$,HWDDF$ ; DCBDF$ ;DEFINE DCB SYMBOLS HWDDF$ ;DEFINE HARDWARE SYMBOLS .IF DF T$$EIO .MCALL PKTDF$ PKTDF$ .ENDC ;T$$EIO .IF DF R$$MPL .MCALL KRBDF$ KRBDF$ ;DEFINE KRB SYMBOLS .IFF ;R$$MPL .MCALL SCBDF$ SCBDF$ ;DEFINE SCB SYMBOLS .ENDC ;R$$MPL .PSECT MAP5 ; ; ; .SBTTL TTCAN - CANCEL I/O ; ;+ ; TTCAN - CANCEL CURRENT IO REQUESTS. ; THIS ROUTINE IS CALLED FROM THE EXECUTIVE TO CANCEL (KILL) ; CURRENT IO REQUESTS FOR A TASK ON A LINE. ; THE UC.KIL BIT IN U.CTL IN THE UCB IS SET FOR ALL TERMINAL ; UNITS TO FORCE THE EXECUTIVE TO CALL THIS ROUTINE ; EVEN THOUGH THE UNIT IS NOT MARKED BUSY. ;- ; ; ; TTCN1 IS CALLED FROM TTINI TO KILL READS OR WRITES (OR BOTH) ; AS REQUESTED FROM AN INTERNAL I/O KILL PACKTET. SELECTION ; IS BASED ON THE SUBFUNCTION BIT IN THE INTERNAL I/O KILL PACKET. ;- ; INPUT: ; R1=>TCB FOR WHICH TO KILL I/O ; R5=>UCB FOR WHICH TO KILL I/O ; R3=>FUNCTION(S) TO KILL (IF ENTRY AT TTCN1) ; ; .ENABL LSB ; TTCAN:: .IF DF R$$IIC MOV #,R3 ;IF CALLED AT TTCAN, BOTH READS ; AND WRITES WILL BE KILLED TTCN1:: .ENDC ;R$$IIC MTPS #0 ;;;ALLOW INTERRUPTS CALL MAPD ;MAP DATA AREA .IF DF T$$EIO MOV R5,R0 ;GET COPY OF UCB POINTER ADD #U.TIXL,R0 ;MAKE POINTER TO U.TIXL (IOPX LISTHEAD) 3$: MOV R0,R4 ;CURRENT IOPX POINTER BECOMES BACKPOINTER ASSUME I.XLNK,0 5$: MOV @R4,R0 ;POINT TO NEXT IOPX BEQ 7$ ;NONE - JUMP CMP I.XTCB(R0),R1 ;DO TASK TCBS MATCH? BNE 3$ ;N - JUMP .IF DF R$$IIC BIT #TF.RLB,R3 ;ARE WE KILLING READS? IF SO, THIS MUST ;HAVE AN IOPX SINCE ONLY READS HAVE IOPX'S BEQ 3$ ;BR IF NO .ENDC ;R$$IIC ASSUME I.XLNK,0 MOV @R0,@R4 ;REMOVE IOPX FROM LIST MOV R1,-(SP) ;SAVE REGISTERS MOV R3,-(SP) MOV #I.XLEN,R1 ;GET SIZE OF IOPX CALL $DEACB ;DEALLOCATE IOPX MOV (SP)+,R3 ;RESTORE REGISTERS MOV (SP)+,R1 BR 5$ ;LOOP 7$: ;REFERENCE LABEL .ENDC ;T$$EIO .IF DF T$$SPL MOV #120000,R4 ;SET VIRTUAL ADDRESS OF UCBX MOV U.TAPR(R5),@#KDSAR5 ;MAP UCBX ADD #U.TSTA,R5 ;POINT TO U.TSTA .IFF ;T$$SPL ADD #U.TUX,R5 ;POINT TO U.TUX ASSUME U.TSTA,U.TUX+2 MOV (R5)+,R4 ;GET UCBX AND POINT TO U.TSTA BEQ 40$ ;NONE - LINE IDLE- JUMP .ENDC ;T$$SPL ASSUME U.TCI,0 MOV @R4,R0 ;GET CURRENT INPUT PACKET BEQ 10$ ;NONE - JUMP BIT #S1.USI,@R5 ;UNSOLICITED INPUT? BNE 10$ ;Y - IGNORE CMP I.TCB(R0),R1 ;FROM THE RIGHT TASK? BNE 10$ ;N - JUMP .IF DF R$$IIC BIT #TF.RLB,R3 ;DO WE WANT TO KILL READS? BEQ 10$ ;BR IF NO .IFTF ;R$$IIC MOV #IE.ABO&377,(R0) ;SET ABORT STATUS MOV R3,-(SP) ;SAVE FLAG FOR KILL READ OR WRITE MOV R1,-(SP) ;SAVE TCB ADDRESS CALL KILLI ;KILL INPUT MOV (SP)+,R1 ;RESTORE TCB ADDRESS MOV (SP)+,R3 ;RESTORE FLAG 10$: MOV U.TCO(R4),R0 ;GET CURRENT OUTPUT PACKET BEQ 40$ ;NONE - JUMP CMP I.TCB(R0),R1 ;FROM THE RIGHT TASK? BNE 40$ ;N - JUMP .IFT ;R$$IIC BIT #TF.WLB,R3 ;DO WE WANT TO KILL WRITES? BEQ 40$ ;BR IF NO .ENDC ;R$$IIC MOV #IE.ABO&377,(R0) ;SET ABORT STATUS BR KILLO ;KILL OUTPUT ; ; .SBTTL KILLO1 - KILL OUTPUT WITH STATUS SUPPLIED IN R0 ;+ ; KILLO1 - KILL OUTPUT WITH STATUS IE.DNR ; USED FOR TIME-OUT OR MODEM HUNG UP. ; ; INPUT: ; R0 - STATUS (IO.DNR IN LO BYTE) ; R4 POINTER TO UCBX ; R5 POINTER TO U.TSTA ; ; REGISTERS ALTERED: R0,R1,R2,R3 ;- ; ; KILLO1::MOV U.TCO(R4),R3 ;GET CURRENT OUTPUT PACKET BNE 20$ ;THERE IS ONE - JUMP BIT #S1.OBY,@R5 ;ECHO IN PROGRESS? BEQ 40$ ;NO - JUMP CALL SETDSI ;YES - DISABLE INPUT PROCESSING BISB #US.OIU,U.STS-U.TSTA(R5) ;INTERRUPTS NOT EXPECTED NOW BIC #S1.OBY,@R5 ;SET OUTPUT FREE RETURN 20$: MOV R0,@R3 ;OK - LOAD STATUS ;FALL THRU TO "KILLO" ; ; .SBTTL KILLO - KILL OUTPUT WITH STATUS IE.ABO ; ;+ ; KILLO - KILL OUTPUT WITH STATUS IE.ABO. ; ; INPUT: ; R4 POINTER TO UCBX ; R5 POINTER TO U.TSTA ; I.LNK IN CURRENT OUTPUT REQUEST PACKET CONTAINS STATUS ; TO RETURN TO TASK ; ; NOTE - MUST EXECUTE ON CORRECT CPU! ; ; REGISTERS ALTERED: R0,R1,R2,R3 ;- ; ; KILLO:: SAVNR ;SAVE R4,R5 CALL SETDSI ;DISABLE INPUT PROCESSING BIC #S2.WRA,2(R5) ;CLEAR WRAP-AROUND CONTEXT CALL ABOXL ;ABORT OUTPUT WITH INTERRUPTS LOCKED OUT BISB #US.OIU,U.STS-U.TSTA(R5) ;DISABLE RECOGNITION OF OUTPUT ;INTERRUPTS FRKBIT BIC,#FR.ORD ;PREVENT MULTIPLE COMPLETIONS CALLR FPORD ;SAY OUTPUT DONE ; ; .SBTTL KILLI1 - KILL INPUT WITH STATUS IN R0 ;+ ; KILLI1 - KILL SOLICITED OR UNSOLICITED INPUT WITH STATUS IN R0. ; USED TO KILL INPUT BECAUSE OF TIME-OUT OR MODEM HUNG UP. ; ; INPUT: ; R0 STATUS (IS.TMO OR IE.DNR) ; R4 POINTER TO UCBX ; R5 POINTER TO U.TSTA ; ; REGISTERS ALTERED: R0,R1,R2,R3 ;- ; ; ASSUME U.TCI,0 KILLI1::MOV @R4,R3 ;GET CURRENT PACKET BEQ 40$ ;NONE - RETURN MOV R0,@R3 ;OK - STORE STATUS ;FALL THRU TO "KILLI" ; ; .SBTTL KILLI - KILL INPUT WITH STATUS IE.ABO ; ;+ ; KILLI - KILL INPUT WITH STATUS IE.ABO. ; ; INPUT: ; R4 POINTER TO UCBX ; R5 POINTER TO U.TSTA ; I.LNK IN CURRENT INPUT REQUEST PACKET CONTAINS STATUS ; TO RETURN TO TASK ; ; NOTE - MUST EXECUTE ON CORRECT CPU! ; ; REGISTERS ALTERED: R0,R1,R2,R3 ;- ; ; KILLI:: SAVNR ;SAVE R4,R5 CALL SETDSI ;DISABLE INPUT PROCESSING TST U.TCO(R4) ;DOING TASK OUTPUT? BNE 30$ ;Y - JUMP ; ; IF WE ARE KILLING A READ WITH ECHO, IT IS POSSIBLE THAT THE ECHO ; HAS NOT YET COMPLETED. IF SO, WE MUST LOGICALLY KILL THE ECHO. ; BISB #US.OIU,U.STS-U.TSTA(R5) ;SET OUTPUT INTERRUPT UNEXPECTED BIC #S1.OBY,@R5 ;SET OUTPUT FREE 30$: FRKBIT BIC,#FR.IRD ;PREVENT MULTIPLE COMPLETIONS BIC #S1.ESC!S1.DEC!S1.DPR,@R5 ;GET OUT OF ESCAPE SEQUENCE MODE ;CLEAR DEFERRED ECHO FLAG ;CLEAR DEFERRED PROCESSING FLAG CLRB U.TISV(R4) ;CLEAR INPUT STATE VARIABLE CALLR FPIRD ;SAY INPUT DONE 40$: RETURN ;RETURN ; ; .IF DF M$$PRO .SBTTL FPTIM - FORK LEVEL TIME-OUT ROUTINE ; ; THIS ROUTINE IS ENTERED FROM THE FORK DISPATCHER AFTER A SWITCH ; TO THE CORRECT CPU TO HANDLE A TIME-OUT. ; .IF DF T$$SPL FPTIM:: CALL 70$ ;HANDLE TIME-OUT ON THIS UNIT .IFF ;T$$SPL ASSUME U.TUX,U.TSTA-2 FPTIM:: TST -(R5) ;POINT TO U.TUX CALL 70$ ;HANDLE TIME-OUT ON THIS UNIT .ENDC ;T$$SPL TST (SP)+ ;ROUTINE RETURNS AS A COROUTINE - POP ;RETURN ADDRESS RETURN ;RETURN TO FORK DISPATCHER .ENDC ;M$$PRO ; ; .SBTTL TIME - TIME-OUT (DRIVER TIMER). ; ; TTICK:: CALL MAPD ;MAP DATA AREA MOV #DCB0,R3 ;POINT TO POINTER TO TT0: DCB MOV #$SCDV1,-(SP) ;GET ADDRESS OF DEVICE TABLE SCAN ROUTINE .IF NDF T$$MOD 80$: .ENDC ;NOT T$$MOD 60$: CALL @(SP)+ ;GET NEXT TERMINAL BCS CLINS ;ALL DONE - JUMP CMP D.NAM(R3),#"TT ;IS DEVICE NAME "TT"? BNE 100$ ;N - ABORT SCAN BIT #DV.TTY,U.CW1(R5) ;IS IT A TERMINAL? BEQ 100$ ;N - ABORT SCAN .IF DF R$$CON BITB #US.OFL,U.ST2(R5) ;IS UNIT OFFLINE? BNE 60$ ;Y - GO ON TO NEXT UNIT .ENDC ;R$$CON ; ; FOUND A TERMINAL. CHECK TIMERS. ; .IF DF T$$SPL ADD #U.TSTA,R5 ;POINT TO U.TSTA 70$: MOV #120000,R4 ;SET VIRTUAL ADDRESS OF UCBX MOV U.TAPR-U.TSTA(R5),@#KDSAR5 ;MAP UCBX .IFF ;T$$SPL ADD #U.TUX,R5 ;POINT TO U.TUX ASSUME U.TSTA,U.TUX+2 70$: MOV (R5)+,R4 ;GET UCBX AND POINT TO U.TSTA .ENDC ;T$$SPL BEQ 80$ ;NONE - JUMP MOV R4,R1 ; ADD #U.TITI,R1 ;POINT TO INPUT TIMER MOV #IS.TMO,R0 ;GET STATUS FOR INPUT TIME-OUT MOV #KILLI1,R2 ;POINT TO KILL INPUT ROUTINE CALL 110$ ;CHECK INPUT TIMER ASSUME S2.CTS,100000 TST 2(R5) ;OUTPUT STOPPED BY CTRL-S? BMI 80$ ;Y - IGNORE OUTPUT TIMER .IF DF T$$SPL MOV #120000,R4 ;RESTORE CLOBBERED R4 TO POINT TO UCBX MOV R4,R1 ; .IFF ;T$$SPL MOV -2(R5),R1 ;GET UCBX .ENDC ;T$$SPL ADD #U.TOTI,R1 ;POINT TO OUTPUT TIMER MOV #IE.DNR&377,R0 ;MOVE STATUS TO R0 FOR KILLO1 MOV #KILLO1,R2 ;POINT TO KILL OUTPUT ROUTINE CALL 110$ ;CHECK OUTPUT TIMER .IF DF T$$MOD 80$: .IF NDF R$$CON BITB #US.OFL,U.ST2-U.TSTA(R5) ;IS UNIT OFFLINE? BEQ 90$ ;N - JUMP CLRB U.TMTI-U.TSTA(R5) ;Y - RESET TIMER TO PREVENT TIMEOUT BR 60$ ;GO ON TO NEXT UNIT .ENDC ;NDF R$$CON 90$: MOV R5,R1 ; ADD #U.TMTI-U.TSTA,R1 ;POINT TO MODEM TIMER MOV #MTIM,R2 ;POINT TO MODEM TIME-OUT ROUTINE CALL 110$ ;CHECK MODEM TIMER .IF DF D$$ZMD MOV #U2.DZ1!U2.RMT,-(SP) ;PUSH BITS TO CHECK BIC U.CW2-U.TSTA(R5),(SP)+ ;IS LINE SERVICED BY A DZ11 AND REMOTE? BNE 60$ ;N - JUMP .IF DF M$$PRO MOV #FR.TIM,R3 ;GET FORK REQUEST BIT FOR MODEM TIMEOUT MOV #60$,-(SP) ;GO ON TO NEXT LINE IF THIS ONE NOT ON THIS CPU CALL SWCPU ;SWITCH TO THE CORRECT CPU IF NECESSARY CALLR YZPOLL ;POLL THE DZ11 FOR MODEM STATUS SINCE IT ;DOESN'T INTERRUPT ON MODEM STATUS TRANSITIONS .IFF ;M$$PRO CALL YZPOLL ;POLL THE DZ11 FOR MODEM STATUS SINCE IT ;DOESN'T INTERRUPT ON MODEM STATUS TRANSITIONS .ENDC ;M$$PRO .ENDC ;D$$ZMD .ENDC ;T$$MOD BR 60$ ;LOOP ; ; FOUND A DEVICE OTHER THAN A TERMINAL - ABORT SCAN ; 100$: ADD #S$$SPA,SP ;FLUSH STACK ; ; ALL DONE - REQUEUE CLOCK BLOCK ; CLINS:: MOV #$TTCB,R0 ;GET CLOCK BLOCK CLR R1 ;CLEAR HIGH ORDER DELTA TIME MOV $TKPS,R2 ;LOW ORDER = 1 SECOND MOV #C.SYST,R4 ;TYPE = SYSTEM SUBROUTINE CALLR $CLINS ;INSERT IN CLOCK QUEUE AND RETURN ; ; 110$: TSTB @R1 ;TIMER ACTIVE? BEQ 120$ ;N - RETURN DECB @R1 ;Y - UPDATE TIMER BEQ 130$ ;TIMER EXPIRED - JUMP 120$: RETURN ;RETURN 130$: .IF DF M$$PRO ; WE JUST DECREMENTED THE TIMER TO 0, BUT WE MAY BE ON THE WRONG CPU. ; SET TIMER BACK TO +1 AND SWITCH TO THE CORRECT CPU. ; INCB @R1 ;SET TIMER TO +1 MOV #FR.TIM,R3 ;GET FORK REQUEST BIT CALL SWCPU ;SWITCH TO CORRECT CPU ; ; IF WE FALL THRU HERE, WE ARE ALREADY ON THE CORRECT CPU. ; CLRB @R1 ;FINALLY SET THE TIMER TO 0 .IF DF T$$SPL MOV #120000,R4 ;RESTORE UCBX POINTER .IFF ;T$$SPL MOV U.TUX-U.TSTA(R5),R4 ;RESTORE UCBX POINTER .ENDC ;T$$SPL .ENDC ;M$$PRO .IF DF T$$CON MOV U.SCB-U.TSTA(R5),R3 ;GET SCB .IF DF R$$MPL MOV S.KRB(R3),R3 ;GET KRB TSTB K.PRM(R3) ;DL11? BNE 140$ ;N - JUMP ASSUME K.CSR,0 MOV @R3,R3 ;GET CSR ADDRESS .IFF ;R$$MPL TSTB U.CTYP-U.TSTA(R5) ;DL11? BNE 140$ ;N - JUMP MOV S.CSR(R3),R3 ;GET CSR ADDRESS .ENDC ;R$$MPL BIT #20,4(R3) ;TERMINAL IN CONSOLE MODE? BNE 120$ ;Y - IGNORE TIME-OUT .ENDC ;T$$CON 140$: JMP @R2 ;HANDLE TIME-OUT ; .DSABL LSB ; .ENABL LSB .IF DF T$$MOD ; ; HANDLE MODEM TIME-OUT ; MTIM: MOV #CT.TIM,R2 ;SET INDEX FOR MODEM TIMEOUT ROUTINE CALLR CTRD ;DO CONTROLLER-DEPENDENT STUFF .ENDC ;T$$MOD ; ; .SBTTL TTPWUP - POWER-UP. ; ;+ ; TTPWUP - POWER-UP. ;- ; ; .IF DF R$$CON TTINIT:: .IFF TTPWUP:: .ENDC .IF DF T$$COM MOV $TTCOM,R0 ;GET TTCOM PCB ADDRESS .IF NDF R$$CON BEQ 20$ ;NOT A VIRGIN SYSTEM - JUMP .ENDC ;NDF R$$CON BIS #PS.NSF,P.STAT(R0) ;MARK TTCOM AS NONSHUFFLABLE MOV P.REL(R0),KINAR6 ;MAP INITIALIZATION CODE IN APR 6 .IF DF T$$SPL CALL INIT ;DO VIRGIN INITIALIZATION .IFF ;T$$SPL CALL INIT+20000 ;DO VIRGIN INITIALIZATION ;THE INIT ROUTINE IS BUILT FOR MAPPING ;IN APR5, BUT IS NOW MAPPED IN APR 6 .ENDC ;T$$SPL 20$: CALL MAPD ;MAP DRIVER DATA AREA .IFF ;T$$COM CALL MAPD ;MAP DATA AREA .IF NDF R$$CON BNE 30$ ;NOT A VIRGIN SYSTEM - JUMP .ENDC ;NDF R$$CON .IF NDF R$$MPL MOV R3,-(SP) ;SAVE R3 MOV R4,-(SP) ;SAVE R4 .IFTF MOV @#KISAR5,R0 ;COPY REAL START OF DRIVER DATA ADD #200,R0 ;ADD THE EQUIVALENT OF 4 K WORDS MOV R0,@#KISAR6 ;MAP REST OF DRIVER .IF NDF T$$SPL MOV R0,@#$DALED ;SAVE DRIVER KISAR6 .ENDC ;NDF T$$SPL CALL INIT ;DO VIRGIN INITIALIZATION .IFT MOV (SP)+,R4 ;RESTORE R4 MOV (SP)+,R3 ;RESTORE R3 .ENDC ;NDF R$$MPL .ENDC ;T$$COM 30$: ;REFERENCE LABEL .IF NDF R$$MPL .IF DF T$$ACD TST U.ACB(R5) ;DOES THIS TERMINAL HAVE AN ACD? BEQ 40$ ;N - JUMP ADD #U.TSTA,R5 ;POINT TO U.TSTA MOV #A.POWE,R0 ;SET POWERFAIL ENTRY POINT CALL $SWACD ;CALL ACD SUB #U.TSTA,R5 ;RESTORE R5 TO UCB ADDRESS .ENDC ;T$$ACD ; SET UP DATABASES OF UCB'S AND CSR'S ; 40$: MOVB U.CTYP(R5),R2 ;GET CONTROLLER TYPE MOV TTUCB(R2),R1 ;POINT TO D'X'UCB ADD R3,R1 ;POINT TO TABLE POINTER FOR THIS CONTROLLER MOV (R1),R1 ;POINT TO UCB/CSR TABLE .IF DF D$$M11 CMP #TTTDH,R2 ;IS IT A DH11? BNE 50$ ;N - JUMP MOV S.DMCS(R4),-2(R1) ;FILL IN DM11-BB CSR .ENDC ;D$$M11 50$: MOV S.CSR(R4),(R1)+ ;FILL IN CONTROLLER CSR MOVB U.UNIT(R5),R2 ;GET UNIT NUMBER ASL R2 ;CONVERT TO WORD OFFSET ADD R2,R1 ;ADD POINTER AND UNIT NUMBER*2 MOV R5,(R1) ;PLUG IN UCB .ENDC ;NDF R$$MPL .IF DF M$$EXT .IF DF D$$H11!D$$V11 .IF DF R$$MPL BIT #HF.UBM,$HFMSK ;UNIBUS MAP EXIST? BEQ 60$ ;N - SKIP INITIALIZATION .IFF ;R$$MPL TST $UMRPT ;UNIBUS MAP EXISTS? BEQ 60$ ;IF EQ NO, SKIP INITIALIZATION .ENDC ; LOAD THE UMR(S) TO MAP DRIVER WITH 18-BIT ADDRESSES IDENTICAL ; TO 16-BIT ADDRESSES ; .IF DF T$$UMR MOV #UMR5S,R1 ;POINT TO SAVED UMR 5 MOV #UBMPR+<5*4>,R2 ;POINT TO UMR 5 MOV (R1)+,(R2)+ ;INITIALIZE UMR 5 MOV (R1)+,(R2)+ .IF NDF T$$SPL MOV (R1)+,(R2)+ ;INITIALIZE UMR 6 MOV (R1)+,(R2)+ .ENDC ;NDF T$$SPL .ENDC ; DF T$$UMR 60$: ;REFERENCE LABEL .ENDC ;D$$H11!D$$V11 .ENDC ;M$$EXT .IF DF R$$CON RETURN .IFF ADD #U.TSTA,R5 ;POINT TO U.TSTA CALL CKTAB ;CHECK WHETHER TYPE-AHEAD BUFFER SHOULD ;BE ALLOCATED OR DEALLOCATED .IF DF T$$MOD BICB #US.CRW!US.DSB,U.STS-U.TSTA(R5) ;ASSUME LOCAL LINE .ENDC MOV #CT.PWR,R2 ;SET ROUTINE INDEX FOR POWER-UP CALLR CTRD ;CALL CONTROLLER DEPENDENT ROUTINE ;AND RETURN .ENDC ;R$$CON .DSABL LSB ; ; .END